<?php

class StatisticsModel
{
    private $statisticsKeyPrefix            =   'S/';
    private $apiStatisticsKeyPrefix         =   'AS/';
    private $snsStatisticsKeyPrefix         =   'SS/';
    private $getChosenDiaryKeyPrefix        =   'DL/';
    private $setChosenDiaryKeyPrefix        =   'T/';
    private $autoCountStatisticsKeyPrefix   =   'AC/';
    private $exchangeSetKeyPrefix           =   'ES/';

    public function localDau($info)/*{{{*/
    {
        if (empty($info['uuid']))
        {
            AC::$errorNo    =   'SM001';
            return  FALSE;
        }

        $dbName     =   'xxtStatistics';
        $tableName  =   'local'. date('Ymd', AC::SERVER_TIME);
        $quarter    =   date('H', AC::SERVER_TIME) * 4 + floor(date('i', AC::SERVER_TIME) / 15);
        $timeQuarter=   sprintf("%2d", $quarter);

        $ip     =   UK::getClientIp();
        $dbSql  =   'INSERT IGNORE INTO '. $dbName. '.'. $tableName. ' (`uuid`, `device`, `timeQuarter`, `time`, `ip`)
                        VALUES("'. $info['uuid']. '", "'. $info['device']. '", "'. $timeQuarter. '", "'. AC::SERVER_TIME. '", "'. $ip. '")';
        $key    =   $this->statisticsKeyPrefix. 0;
        $result =   Storage::execDbSentence($key, $dbSql);

        global $_G;
	    $host_name = empty($_G['serverHost']) ? "na" : $_G['serverHost'];
        $jobdata = array(
                "uuid" =>     $info['uuid'],
                "device" => $info['device'],
                "timeQuarter" => $timeQuarter,
                "time" => AC::SERVER_TIME,
                "ip" => $ip,
                "topic" => "api",
                "source" => $host_name,
                "ymd" => date('Ymd', AC::SERVER_TIME),
        );
        //RedisPool::addGearmanJob("apilog_device", $jobdata);
        return  $result;
    }/*}}}*/

    public function apiStatistics($info)/*{{{*/
    {
        if (empty($info['do']))
        {
            #   AC::$errorNo    =   'SM002';
            return  FALSE;
        }
        $newApi = array('getDiaryDetail',
        		 'getUserFeedList',
        		 'getHotDiary',
        		 'getUserDiaryList',
        		 'getSearchDiary',
        		 'getMeLikeDiaryList',
        		'getLikesMe',
                'getCommentsToMe',
        		 'getCommentsByMe',
        		 'postReview',
        		 'modifyUserInfo',
        		 'recommentUserList',
        		 'getFollowLikes',
        		 'getRecommentUserList',
        		'push',
        		'bind',
        		'common'
        );
        
        $oldApi = array(
        		'getDiaryInfoWithCommentReply',
        		 'getFeedList',
        		 'getChosenDiary',
        		 'getDiaryList',
        		 'fetchDiaryInfo',
        		 'getMeLikeList',
        		 'getMeLikeList',
        		'getCommentMeList',
        		 'getMeCommentList',
        		 'postComment',
        		 'editUserInfo',
        		 'getDiaryList',
        		 'getLikeMeList',
        		 'fetchUserInfo',
        		'getMeLikeList',
        		'getMeLikeList',
        		'getDiaryInfoWithCommentReply'
        		
        );
        $tmp = array_search($info['do'], $newApi);
        
        if ($tmp >= 0){
            $info['do'] = $oldApi[$tmp];
        }
        
        $dbTableName=   'xxtStatistics.apiStatistics';
        $quarter    =   date('H', AC::SERVER_TIME) * 4 + floor(date('i', AC::SERVER_TIME) / 15);
        $timeQuarter=   sprintf("%2d", $quarter);
        $ymd        =   date('Ymd', AC::SERVER_TIME);
        $dbSql      =   'UPDATE '. $dbTableName. ' SET api = api + 1 , '. $info['do']. ' = '. $info['do']. ' + 1 WHERE ymd = "'. $ymd. '" AND timeQuarter = "'. $timeQuarter. '"';

        $key    =   $this->apiStatisticsKeyPrefix. 0;
        $result =   Storage::execDbSentence($key, $dbSql);
        return  $result;
    }/*}}}*/

    public function snsDau($info)/*{{{*/
    {
        if (empty($info['uid']))    $info['uid']    =   0;

        $dbName     =   'xxtDau';
        $tableName  =   'dau'. date('Ymd', AC::SERVER_TIME);
        $quarter    =   date('H', AC::SERVER_TIME) * 4 + floor(date('i', AC::SERVER_TIME) / 15);
        $timeQuarter=   sprintf("%2d", $quarter);
        $dbSql      =   'INSERT INTO '. $dbName. '.'. $tableName. ' (`uid`, `timeQuarter`, `times`) VALUES ("'. $info['uid']. '", "'. $timeQuarter. '", "1") ON DUPLICATE KEY UPDATE times = times + 1 ';
        $statDo     =   $this->statDoing($info['do']);

        global $_G;
        $host_name = empty($_G['serverHost']) ? "na" : $_G['serverHost'];
        $jobdata = array(
                "uid" =>    $info['uid'],
                "timeQuarter" => $timeQuarter,
                "times" => 1,
                "statDo" => $info['do'],
                "time" =>  AC::SERVER_TIME,
                "topic" => "api",
                "source" => $host_name,
                "ymd" => date('Ymd', AC::SERVER_TIME)
        );
        if (!empty($statDo))
        {
            $dbSql  =   'INSERT INTO '. $dbName. '.'. $tableName. ' (`uid`, `timeQuarter`, `times`, `'. $statDo. '`) VALUES ("'. $info['uid']. '", "'. $timeQuarter. '", "1", "1")
                         ON DUPLICATE KEY UPDATE times = times + 1, '. $statDo. '= '. $statDo. ' + 1 ';
            $jobdata["statDo"] = $statDo;
        }
        //RedisPool::addGearmanJob("apilog_dau", $jobdata);

        $key    =   $this->snsStatisticsKeyPrefix. $info['uid'];
        $result =   Storage::execDbSentence($key, $dbSql);
        return  $result;
    }/*}}}*/

    public function getSnsDau($info)/*{{{*/
    {
        $today  =   date('Ymd', AC::SERVER_TIME);
        if (empty($info['ymd']) ||  $info['ymd'] >  $today) $info['ymd']    =   $today;
        $time       =   strtotime($info['ymd']);
        $endTime    =   $time + 86400;
        $lastTime   =   $time - 1;

        $dbSql  =   '
                    SELECT * FROM 
                    (
                        SELECT "社区总DAU"              AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "社区总PV"               AS stat,    SUM(times)      AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "聊天室DAU"              AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. ' WHERE chats > 0       UNION
                        SELECT "聊天室PV"               AS stat,    SUM(chats)      AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "同步DAU"                AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. ' WHERE cloudSyncs > 0  UNION
                        SELECT "同步PV"                 AS stat,    SUM(cloudSyncs) AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "评论DAU"                AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. ' WHERE comments > 0    UNION
                        SELECT "评论PV"                 AS stat,    SUM(comments)   AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "分享日记DAU"            AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. ' WHERE diarys > 0      UNION
                        SELECT "分享日记PV"             AS stat,    SUM(diarys)     AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "关注DAU"                AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. ' WHERE follows > 0     UNION
                        SELECT "关注PV"                 AS stat,    SUM(follows)    AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "喜欢DAU"                AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. ' WHERE likes > 0       UNION
                        SELECT "喜欢PV"                 AS stat,    SUM(likes)      AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "站内信DAU"              AS stat,    COUNT(*)        AS num  FROM xxtDau.dau'. $info['ymd']. ' WHERE messages > 0    UNION
                        SELECT "站内信PV"               AS stat,    SUM(messages)   AS num  FROM xxtDau.dau'. $info['ymd']. '                       UNION
                        SELECT "注册成功数(总数)"       AS stat,    COUNT(*)        AS num  FROM xxtUser.autoUid_0 WHERE registerTime > '. $lastTime. ' AND registerTime < '. $endTime. ' UNION
                        SELECT "注册成功数(微博)"       AS stat,    COUNT(*)        AS num  FROM xxtUser.autoUid_0 WHERE platform = "weibo" AND registerTime > '. $lastTime. ' AND registerTime < '. $endTime. ' UNION
                        SELECT "注册成功数(QQ)"         AS stat,    COUNT(*)        AS num  FROM xxtUser.autoUid_0 WHERE platform = "qq" AND registerTime > '. $lastTime. ' AND registerTime < '. $endTime. ' UNION
                        SELECT "注册成功数(Wechat)"         AS stat,    COUNT(*)        AS num  FROM xxtUser.autoUid_0 WHERE platform = "wechat" AND registerTime > '. $lastTime. ' AND registerTime < '. $endTime. ' UNION
                        SELECT "粉粉账户注册请求数(不含第三方)"     AS stat,    SUM(registers)  AS num  FROM xxtDau.dau'. $info['ymd']. ' 
                    ) as b';

        $key    =   $this->snsStatisticsKeyPrefix. 0;
        $result =   Storage::fetchDbSentence($key, $dbSql, 2);
        return  $result;
    }/*}}}*/

    public function getSnsQuarter($info)/*{{{*/
    {
        # api, registerUser, writeDiary, meFollow, postComment, postLike, postChat, cloudSync, sendMessage
        $interactiveType    =   array(
                                    'times'     =>  'api',
                                    'chats'     =>  'postChat',
                                    'cloudSync' =>  'cloudSync',
                                    'comments'  =>  'postComment',
                                    'diarys'    =>  'writeDiary',
                                    'follows'   =>  'meFollow',
                                    'likes'     =>  'postLike',
                                    'messages'  =>  'sendMessage',
                                    'registers' =>  'registerUser',
                                );
        if (empty($interactiveType[$info['type']])) return  ' Error : Type is not exists! ';

        $today  =   date('Ymd', AC::SERVER_TIME);
        if (empty($info['ymd']) ||  $info['ymd'] >  $today) $info['ymd']    =   $today;

        $dbSql  =   ' SELECT timeQuarter, '. $interactiveType[$info['type']]. ' as num FROM xxtStatistics.apiStatistics WHERE ymd="'. $info['ymd']. '" ORDER BY timeQuarter ASC ';
        $key    =   $this->apiStatisticsKeyPrefix. 0;
        $result =   Storage::fetchDbSentence($key, $dbSql, 2);
        return  $result;
    }/*}}}*/

    public function getTotalExchange($info)/*{{{*/
    {
        $dbSql  =   ' SELECT s.title AS 换量应用名称, s.comeGo AS 换量方向, sum(c.num) AS 下载次数 FROM xxtStatistics.autoCount_0 as c, xxtStatistics.autoCountSet_0 as s WHERE s.id = c.markId GROUP BY c.markId ';

        $key    =   $this->autoCountStatisticsKeyPrefix. 0;
        $result =   Storage::fetchDbSentence($key, $dbSql, 2);
        return  $result;
    }/*}}}*/

    public function getDailyExchange($info)/*{{{*/
    {
        $length =   date('Ymd', AC::SERVER_TIME - 3 * 86400);
        $dbSql  =   ' SELECT c.ymd AS 下载日期, s.title AS 换量应用名称, s.comeGo AS 换量方向, sum(c.num) AS 下载次数 FROM xxtStatistics.autoCount_0 as c, xxtStatistics.autoCountSet_0 as s 
                      WHERE s.id = c.markId AND c.ymd > "'. $length. '" GROUP BY c.ymd, c.markId ORDER BY c.ymd DESC ';
        if (!empty($info['ymd']))
        {
            $dbSql  =   ' SELECT s.title AS 换量应用名称, s.comeGo AS 换量方向, sum(c.num) AS 下载次数 FROM xxtStatistics.autoCount_0 as c, xxtStatistics.autoCountSet_0 as s WHERE s.id = c.markId AND c.ymd ="'. $info['ymd']. '" GROUP BY c.markId ';
        }


        $key    =   $this->autoCountStatisticsKeyPrefix. 0;
        $result =   Storage::fetchDbSentence($key, $dbSql, 2);
        return  $result;
    }/*}}}*/

    public function getExchangeList($info)/*{{{*/
    {
        $dbSql  =   ' SELECT * FROM xxtStatistics.exchangeSet_0 WHERE exchangeStatus =0 ORDER BY appRanking DESC ';
        if (!empty($info['appPlatform']))
        {
            $dbSql  =   ' SELECT * FROM xxtStatistics.exchangeSet_0 WHERE exchangeStatus = 0 AND appPlatform = "'. $info['appPlatform']. '" ORDER BY appRanking DESC ';
        }
    
        $key    =   $this->exchangeSetKeyPrefix. 0;
        $result =   Storage::fetchDbSentence($key, $dbSql, 2);
        return  $result;
    }/*}}}*/
    
    public function getChosenDiary($info)/*{{{*/
    {
        $timesArray =   array(
                            'likeTimes'     =>  1,
                            'grossScore'    =>  1,
                            'commentTimes'  =>  1,
                        );
        if (empty($timesArray[$info['timesType']])) $info['timesType']  =   'grossScore';

        $hour       =   date('H', SERVER_TIME);
        $periodType =   floor($hour / 6) + 1;

        $minute     =   date('i', SERVER_TIME);
        $topMinute  =   floor($minute / 15);
        $selectIndex=   $topMinute % 2;

        $info['periodType'] =   $periodType;

        $start      =   isset($info['start'])  ?    $info['start'] :   0;
        $length     =   isset($info['length']) ?    $info['length']:   AC::DIARY_LIST_DEFAULT_LEN;

        $selectTable=   'topN_'. $selectIndex;
        $selectSql  =   'SELECT * FROM xxtMessage.'. $selectTable. ' WHERE chosen = 0 ORDER BY '. $info['timesType']. ' DESC limit '. $start. ', '. $length;
        $keyClient  =   $this->setChosenDiaryKeyPrefix. $selectIndex;
        $result     =   Storage::fetchDbSentenceByClient($keyClient, $selectSql, 2);
        return  $result;
    }/*}}}*/

    public function getChosenByEditor($info = NULL)/*{{{*/
    {
        $minute     =   date('i', SERVER_TIME);
        $topMinute  =   floor($minute / 15);
        $selectIndex=   $topMinute % 2;

        $start      =   isset($info['start'])  ?    $info['start'] :   0;
        $length     =   isset($info['length']) ?    $info['length']:   AC::DIARY_LIST_DEFAULT_LEN;

        $selectTable=   'topN_'. $selectIndex;
        $selectSql  =   'SELECT * FROM xxtMessage.'. $selectTable. ' WHERE chosen > 0 ORDER BY chosen DESC limit '. $start. ', '. $length;
        $keyClient  =   $this->setChosenDiaryKeyPrefix. $selectIndex;
        $result     =   Storage::fetchDbSentenceByClient($keyClient, $selectSql);
        return  $result;
    }/*}}}*/

    public function removeChosenDiary($deleteIndex)/*{{{*/
    {
        $deleteTable=   'topN_'. $deleteIndex;
        $deleteSql  =   'DELETE FROM xxtMessage.'. $deleteTable. ' WHERE chosen = 0 ';;
        $keyClient  =   $this->setChosenDiaryKeyPrefix. $deleteIndex;
        $result     =   Storage::execDbSentenceByClient($keyClient, $deleteSql);
        return  $result;
    }/*}}}*/

    public function countChosenDiary($info)/*{{{*/
    {
        $timesArray =   array(
                            'viewTimes'     =>  1,
                            'likeTimes'     =>  1,
                            'commentTimes'  =>  1,
                            'grossScore'    =>  1,
                        );
        $periodArray=   array(
                            1   =>  0,          # all
                            2   =>  86400 * 30, # 30D
                            3   =>  86400 * 7,  # 7D
                            4   =>  86400,      # 24H
                        );
        if (!isset($periodArray[$info['periodType']]))  return  NULL;
        $selectTable    =   'diaryList_'. $info['index'];
        $periodType     =   $info['periodType'];

        if (empty($periodArray[$periodType]))   $where  =   ' WHERE secret = 0 ';
        else    $where  =   ' WHERE secret = 0 AND time > '. (AC::SERVER_TIME - $periodArray[$periodType]);

        if (empty($timesArray[$info['timesType']]))     return  NULL;

        $selectSql  =   'SELECT uid, uid AS nickname, bodyId, '. AC::FEED_DIARY. ' AS type, title, abbreviation, time, status, '. $periodType. ' AS periodType, viewTimes, commentTimes, likeTimes, attachmentPath, commentPeople, (likeTimes + commentPeople) AS grossScore FROM xxtDiaryKit.'. $selectTable. $where. ' ORDER BY '. $info['timesType']. ' DESC limit 20' ;
        $keyClient  =   $this->getChosenDiaryKeyPrefix. $info['index'];
        $top20      =   Storage::fetchDbSentenceByClient($keyClient, $selectSql, 2);
        return  $top20;
    }/*}}}*/

    public function setChosenDiary($top20, $insertIndex)/*{{{*/
    {
        $insertTable=   'topN_'. $insertIndex;

        $insertValue=   array();
        foreach ($top20 as  $record)
        {
            if (empty($record)  ||  !is_array($record)) continue;

            $insertValue[]  =   "'". implode("', '", $record). "'";
        }
        if (empty($insertValue))    return  NULL;
        $values     =   '('. implode('), (', $insertValue). ')';
        $insertSql  =   'INSERT IGNORE INTO xxtMessage.'. $insertTable. ' (eUid, eNickname, bodyId, type, title, abbreviation, time, status, periodType, viewTimes, commentTimes, likeTimes, attachmentPath, commentPeople, grossScore) VALUES '. $values. ' 
                         ON DUPLICATE KEY UPDATE commentTimes=VALUES(commentTimes), likeTimes=VALUES(likeTimes), commentPeople=VALUES(commentPeople), grossScore=VALUES(grossScore)';
        $keyClient  =   $this->setChosenDiaryKeyPrefix. $insertIndex;
        $result     =   Storage::execDbSentenceByClient($keyClient, $insertSql);
        return  $result;
    }/*}}}*/

    private function statDoing($do)/*{{{*/
    {
        $needStatDo =   array(
            'postChat'      =>  'chats',
            'cloudSync'     =>  'cloudSyncs',
            'postComment'   =>  'comments',
            'writeDiary'    =>  'diarys',
            'meFollow'      =>  'follows',
            'postLike'      =>  'likes',
            'sendMessage'   =>  'messages',
            'registerUser'  =>  'registers',
        );

        if (empty($needStatDo[$do]))    return  NULL;

        return  $needStatDo[$do];
    }/*}}}*/

}

